package com.example.springevent.demos;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;

public class Event03PublisherDemo implements ApplicationContextAware, ApplicationEventPublisherAware {
	
	private ApplicationContext contextAware;
	private ApplicationEventPublisher eventPublisherAware;
	
	// 推荐依赖注入ApplicationContext
	@Autowired
	private ApplicationContext applicationContext;
	
	@Autowired
	// 依赖注入ApplicationEventPublisher
	private ApplicationEventPublisher applicationEventPublisher;
	@Autowired
	// 依赖注入ApplicationEventMulticaster
	private ApplicationEventMulticaster applicationEventMulticaster;

	public static void main(String[] args) {
		// 创建注解驱动 Spring 应用上下文
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

		// 注册 @Configuration 类
		context.register(Event03PublisherDemo.class);

		// 添加 Spring 事件监听器
		context.addApplicationListener(new DemoEventListener());

		// 启动 Spring 应用上下文
		context.refresh();

		// 发布 Spring 事件
		context.publishEvent(new DemoEvent("event-hello world1"));
		
		Event03PublisherDemo demo = context.getBean(Event03PublisherDemo.class);
		demo.applicationContext.publishEvent(new DemoEvent("event-hello world2"));
		demo.contextAware.publishEvent(new DemoEvent("event-hello world3"));
		demo.applicationEventPublisher.publishEvent(new DemoEvent("event-hello world4"));
		demo.eventPublisherAware.publishEvent(new DemoEvent("event-hello world5"));
		demo.applicationEventMulticaster.multicastEvent(new DemoEvent("event-hello world6"));
		
		System.out.println(demo.applicationContext == context);
		System.out.println(demo.applicationContext == demo.contextAware);
		System.out.println(demo.applicationContext == demo.applicationEventPublisher);
		System.out.println(demo.applicationContext == demo.eventPublisherAware);
		
		// 依赖查找
		ApplicationEventMulticaster multicaster = context.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
		multicaster.multicastEvent(new DemoEvent("event-hello world7"));
		System.out.println(demo.applicationEventMulticaster == multicaster);

		// 关闭 Spring 应用上下文
		context.close();
	}

	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
		// Aware接口setter注入		
		// @see org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization
		this.eventPublisherAware = applicationEventPublisher;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// Aware接口setter注入
		// @see org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization
		this.contextAware = applicationContext;
	}

}
